package com.moli.iov.manager.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moli.iov.cache.RedisUtil;
import com.moli.iov.manager.ManagerConstant;
import com.moli.iov.manager.enums.YesOrNoEnum;
import com.moli.iov.manager.mapper.DictDataMapper;
import com.moli.iov.manager.model.dto.DictDataQueryByCodeDto;
import com.moli.iov.manager.model.dto.DictDataQueryByTypeDto;
import com.moli.iov.manager.model.dto.DictTypeDto;
import com.moli.iov.manager.model.po.DictData;
import com.moli.iov.manager.service.IDictDataService;
import com.moli.iov.rest.RestResponse;
import com.moli.iov.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 字典 服务实现类
 * </p>
 *
 * @author zph
 * @since 2018-12-11
 */
@Service("dictDataService")
public class DictDataServiceImpl extends ServiceImpl<DictDataMapper, DictData> implements IDictDataService {

    private Logger logger = LoggerFactory.getLogger(DictDataServiceImpl.class);

    @Autowired
    DictDataMapper dictDataMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public RestResponse<Map<String, Map<String, String>>> queryDictMaps(DictTypeDto dictTypeDto) {

        logger.info("[获取字典map集合 入参][DictTypeDto:{}]", dictTypeDto.toString());

        if (dictTypeDto != null && dictTypeDto.getTypes() != null && dictTypeDto.getTypes().size() > 0) {
            Set<String> typeList = dictTypeDto.getTypes();
            Map<String, Map<String, String>> result = new HashMap<>();

            for (String type : typeList) {
                DictDataQueryByTypeDto dictDataQueryByTypeDto = new DictDataQueryByTypeDto();
                dictDataQueryByTypeDto.setDictType(type);
                RestResponse<Map<String, String>> tmpMap = this.queryMapByType(dictDataQueryByTypeDto);
                if (tmpMap != null && tmpMap.isFlag() && tmpMap.getData() != null) {
                    result.put(type, tmpMap.getData());
                }
            }
            return RestResponse.success(result);
        }
        return RestResponse.failure("查询参数为空");
    }

    /**
     * 获取value值
     *
     * @param dictDataQueryByCodeDto
     * @return
     */
    @Override
    public RestResponse queryValueByCode(DictDataQueryByCodeDto dictDataQueryByCodeDto) {
        logger.info("获取字典value值：{}" + dictDataQueryByCodeDto);
        RestResponse restResponse = new RestResponse();
        try {
            String dictCode = dictDataQueryByCodeDto.getDictCode();
            String dictType = dictDataQueryByCodeDto.getDictType();

            if (StringUtils.isNotBlank(dictCode) && StringUtils.isNotBlank(dictType)) {
                QueryWrapper<DictData> queryWrapper = new QueryWrapper<DictData>();
                queryWrapper.eq("dict_code", dictCode);
                queryWrapper.eq("dict_type", dictType);
                queryWrapper.eq("is_fixed", YesOrNoEnum.YES.getCode());
                DictData dictData = dictDataMapper.selectOne(queryWrapper);
                if (dictData != null) {
                    restResponse.setData(dictData.getDictValue());
                }
                return restResponse;
            } else {
                logger.error("字典Code或类型为空");
                return RestResponse.failure("字典Code或类型为空");
            }
        } catch (Exception e) {
            logger.error("获取字典value值失败", e);
            return RestResponse.failure("获取字典value值失败");
        }
    }

    /**
     * 根据类型获取字典
     *
     * @param dictDataQueryByTypeDto
     * @return
     */
    @Override
    public RestResponse<List<DictData>> queryListByType(DictDataQueryByTypeDto dictDataQueryByTypeDto) {
        if (dictDataQueryByTypeDto == null || StringUtil.isBlank(dictDataQueryByTypeDto.getDictType())) {
            return RestResponse.failure("根据类型获取字典信息失败");
        }
        String jsonDictData = redisUtil.get(ManagerConstant.DICT_MAP_PREFIX + dictDataQueryByTypeDto.getDictType());
        List<DictData> dictDataList = JSONArray.parseArray(jsonDictData, DictData.class);
        if (dictDataList != null && dictDataList.size() > 0) {
            return RestResponse.success(dictDataList);
        }
        RestResponse<List<DictData>> restResponse = new RestResponse<List<DictData>>();
        try {
            String dictType = dictDataQueryByTypeDto.getDictType();
            if (StringUtils.isNotBlank(dictType)) {
                QueryWrapper<DictData> queryWrapper = new QueryWrapper<DictData>();
                queryWrapper.eq("dict_type", dictType);
                queryWrapper.eq("is_fixed", YesOrNoEnum.YES.getCode());
                List<DictData> list = dictDataMapper.selectList(queryWrapper);
                restResponse.setData(list);
                return restResponse;
            } else {
                logger.error("字典类型为空");
                return RestResponse.failure("字典类型为空");
            }
        } catch (Exception e) {
            logger.error("根据类型获取字典信息失败", e);
            return RestResponse.failure("根据类型获取字典信息失败");
        }
    }

    /**
     * 根据类型获取字典信息
     *
     * @param dictDataQueryByTypeDto
     * @return
     */
    @Override
    public RestResponse<Map<String, String>> queryMapByType(DictDataQueryByTypeDto dictDataQueryByTypeDto) {
//        logger.info("根据类型获取字典信息：{}" + dictDataQueryByTypeDto);
        if (dictDataQueryByTypeDto == null || StringUtil.isBlank(dictDataQueryByTypeDto.getDictType())) {
            return RestResponse.failure("根据类型获取字典信息失败");
        }
        String jsonDictData = redisUtil.get(ManagerConstant.DICT_MAP_PREFIX + dictDataQueryByTypeDto.getDictType());
        List<DictData> dictDataList = JSONArray.parseArray(jsonDictData, DictData.class);
        if (dictDataList != null && dictDataList.size() > 0) {
            Map<String, String> map = new HashMap<String, String>();
            for (DictData dictData : dictDataList) {
                map.put(dictData.getDictCode(), dictData.getDictValue());
            }
            return RestResponse.success(map);
        }
        RestResponse<Map<String, String>> restResponse = new RestResponse<Map<String, String>>();
        try {
            String dictType = dictDataQueryByTypeDto.getDictType();
            if (StringUtils.isNotBlank(dictType)) {
                QueryWrapper<DictData> queryWrapper = new QueryWrapper<DictData>();
                queryWrapper.eq("dict_type", dictType);
                queryWrapper.eq("is_fixed", YesOrNoEnum.YES.getCode());
                List<DictData> list = dictDataMapper.selectList(queryWrapper);
                Map<String, String> map = new HashMap<String, String>();

                for (int i = 0; i < list.size(); i++) {
                    DictData dictData = list.get(i);
                    map.put(dictData.getDictCode(), dictData.getDictValue());
                }

                restResponse.setData(map);
                return restResponse;
            } else {
                logger.error("字典类型为空");
                return RestResponse.failure("字典类型为空");
            }
        } catch (Exception e) {
            logger.error("根据类型获取字典信息失败", e);
            return RestResponse.failure("根据类型获取字典信息失败");
        }
    }


    @Override
    public RestResponse<Map<String, List<DictData>>> queryBasicDicinfos() {
        return queryBasicDicinfos(null);
    }

    @Override
    public RestResponse queryBasicDicinfos(String dictCode) {

        List<DictData> ditList = new ArrayList<>();
        if (StringUtil.isBlank(dictCode)) {
            dictCode = "CLPP";
        }
        DictDataQueryByTypeDto dictDataQueryByTypeDto = new DictDataQueryByTypeDto();
        dictDataQueryByTypeDto.setDictType(dictCode);
        RestResponse<List<DictData>> listRestResponse = queryListByType(dictDataQueryByTypeDto);
        if (listRestResponse != null && listRestResponse.getCode() == 0) {
            ditList = listRestResponse.getData();
            for (DictData datum : ditList) {
                List<DictData> dictDataList = queryChildDict(datum.getId());
                datum.setChild(dictDataList);
            }
        }
        try {
            String jsonString = JSONArray.toJSONString(ditList);
            redisUtil.set(ManagerConstant.BASE_DICT, jsonString);
            return RestResponse.success(ditList);
        } catch (Exception e) {
            e.printStackTrace();
            return RestResponse.failure("获取字典信息失败");
        }
    }


    public List<DictData> queryChildDict(long pid) {
        List<DictData> dictDataList = new ArrayList<>();
        List<DictData> dictDataList1 = queryChildDictDatasByPid(pid);
        for (DictData dictData : dictDataList1) {
            List<DictData> dictData1 = queryChildDict(dictData.getId());
            if (dictData1 != null && dictData1.size() == 0) {
                dictData1 = null;
            }
            dictData.setChild(dictData1);
            dictDataList.add(dictData);
        }
        return dictDataList;
    }

    public List<DictData> queryChildDictDatasByPid(long pid) {

        QueryWrapper<DictData> queryWrapper = new QueryWrapper();
        queryWrapper.eq("pid", pid);
        queryWrapper.eq("is_fixed", 1);
        return list(queryWrapper);
    }

    @Override
    public RestResponse<List<DictData>> queryDictsByPcode(Integer pcode, String dictType) {
        QueryWrapper<DictData> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("dict_code", pcode);
        queryWrapper.eq("dict_type", dictType);
        queryWrapper.eq("is_fixed", 1);
        DictData dictData = dictDataMapper.selectOne(queryWrapper);
        if (null != dictData) {
            QueryWrapper<DictData> queryWrapper2 = new QueryWrapper();
            queryWrapper2.eq("pid", dictData.getId());
            queryWrapper2.eq("is_fixed", 1);
            return RestResponse.success(list(queryWrapper2));
        } else {
            return RestResponse.success(new ArrayList<DictData>(0));
        }

    }

    @Override
    public RestResponse<Map<String, List<DictData>>> queryAllDicts() {
        QueryWrapper<DictData> queryWrapper = new QueryWrapper<DictData>();
        queryWrapper.eq("is_fixed", YesOrNoEnum.YES.getCode());
        List<DictData> list = dictDataMapper.selectList(queryWrapper);

        if (list == null || list.size() <= 0) {
            RestResponse.failure("查询所有字典失败");
        }
        Map<String, List<DictData>> listMap = new HashMap<>();
        for (DictData dictData : list) {
            String dictType = dictData.getDictType();
            List<DictData> dictDataList = listMap.get(dictType);
            if (dictDataList == null) {
                dictDataList = new ArrayList<>();
            }
            dictDataList.add(dictData);
            listMap.put(dictType, dictDataList);
        }
        return RestResponse.success(listMap);
    }

    @Override
    public RestResponse cacheAllDict() {

        try {
            RestResponse<Map<String, List<DictData>>> restResponse = queryAllDicts();
            if (restResponse != null && restResponse.getCode() == 0) {
                Map<String, List<DictData>> listMap = restResponse.getData();
                if (listMap != null && listMap.size() > 0) {
                    Set<Map.Entry<String, List<DictData>>> entries = listMap.entrySet();
                    for (Map.Entry<String, List<DictData>> entry : entries) {
                        String dictType = entry.getKey();
                        List<DictData> dictDataList = entry.getValue();
                        String jsonString = JSONArray.toJSONString(dictDataList);
                        redisUtil.set(ManagerConstant.DICT_MAP_PREFIX + dictType, jsonString);
                    }
                }
            }

            redisUtil.delete(ManagerConstant.DICT_MAP_TYPE);
            List<DictData> list = queryAll();
            if(list!=null && list.size()>0){
                Map<String,String> map = new HashMap<>();
                for (DictData dictData : list) {
                    if(dictData!=null
                            && StringUtils.isNotBlank(dictData.getDictCode())
                            && StringUtils.isNotBlank(dictData.getDictType())){
                        String value = map.get(dictData.getDictType());
                        if(value==null) {
                            value="";
                        }
                        value+=(dictData.getDictType()
                                +ManagerConstant.DICT_MAP_TYPE_CONNECTOR
                                +dictData.getDictCode()
                                +ManagerConstant.DICT_MAP_TYPE_CONNECTOR
                                +dictData.getDictValue()
                                +ManagerConstant.DICT_MAP_TYPECODEVALUE_CONNECTOR);
                        map.put(dictData.getDictType(),value);
                    }
                }
                redisUtil.hset(ManagerConstant.DICT_MAP_TYPE,map);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("缓存字典信息失,message:" + e.getMessage());
            return RestResponse.success("缓存字典信息失败");
        }
        return RestResponse.success("缓存字典信息成功");
    }

    private List<DictData> queryAll(){
        QueryWrapper<DictData> queryWrapper = new QueryWrapper<DictData>();
        queryWrapper.eq("is_fixed", YesOrNoEnum.YES.getCode());
        List<DictData> list = dictDataMapper.selectList(queryWrapper);
        return list;
    }
}
